package com.wisdytech.common.shiro;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.wisdytech.linkdcs.log.service.ISysLogService;
import com.wisdytech.linkdcs.system.dao.ISysResourceDao;
import com.wisdytech.linkdcs.system.model.SysResource;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Configuration
public class ShiroConfig {
	@Autowired
	private ISysResourceDao iSysResourceDao;

    @Bean
    public FilterRegistrationBean shiroLoginFilterRegistration(ShiroLoginFilter shiroLoginFilter) {
        FilterRegistrationBean registration = new FilterRegistrationBean(shiroLoginFilter);
        registration.setEnabled(false);
        return registration;
    }

    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }


    @Bean
	public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
		
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
         
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        //自定义过滤
        Map<String, Filter> filters =shiroFilterFactoryBean.getFilters();
        filters.put("log", systemLogFilter());
        filters.put("authc",shiroLoginFilter());
        shiroFilterFactoryBean.setFilters(filters);
        
        //url过滤
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
        // 配置不会被拦截的链接 顺序判断
        filterChainDefinitionMap.put("/3thExt/**", "anon");
        filterChainDefinitionMap.put("/webjars/**", "anon");
        filterChainDefinitionMap.put("/webjarslocator/**", "anon");
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/image/**", "anon");
        //组态设计接口不拦截
        filterChainDefinitionMap.put("/equipment/configuration/design/**", "anon");
        filterChainDefinitionMap.put("/webSocketServer/**", "anon");
        
        filterChainDefinitionMap.put("/doLogin", "anon");
        //初始化所要拦截的资源
        EntityWrapper<SysResource> ew = new EntityWrapper<>();
        List<SysResource> sysResourceList = iSysResourceDao.selectList(ew);
        for(SysResource sysResource : sysResourceList) {
        	if(sysResource.getPermission() != null) {
        		filterChainDefinitionMap.put("/"+sysResource.getUri(), "perms["+sysResource.getPermission()+"]");
        	}
        }

        filterChainDefinitionMap.put("/demo/**", "authc,roles[admin]");

        //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
        filterChainDefinitionMap.put("/logout", "logout");
        //<!-- 过滤链定义，从上向下顺序执行，一般将/**放在最为下边 -->:这是一个坑呢，一不小心代码就不好使了;
        //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
        filterChainDefinitionMap.put("/**", "authc");
        
        //针对页面url请求过滤
        filterChainDefinitionMap.put("/**/index", "log");
        filterChainDefinitionMap.put("/**/*.mvc", "log");



        
        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/index");

        //未授权界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/system/user/unauthorized");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
	}


    @Bean
    public ShiroLoginFilter shiroLoginFilter() {
        //SystemLogFilter systemLogFilter = new SystemLogFilter();
        return new ShiroLoginFilter();
    }


	@ConditionalOnBean(ISysLogService.class)
	@Bean
	public SystemLogFilter systemLogFilter() {
		//SystemLogFilter systemLogFilter = new SystemLogFilter();
		return new SystemLogFilter();
	}
	
	@Bean
    public MyShiroRealm myShiroRealm(){
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        return myShiroRealm;
    }
	
	@Bean
	public DefaultWebSessionManager defaultWebSessionManager() {
		DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); 
        //sessionManager.setGlobalSessionTimeout(6000000);
		sessionManager.setGlobalSessionTimeout(1000*60*30);
        sessionManager.setDeleteInvalidSessions(true);  
        sessionManager.setSessionValidationSchedulerEnabled(true);  
        sessionManager.setDeleteInvalidSessions(true);
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        //sessionManager.setSessionIdCookie(simpleCookie());
        return sessionManager;  
	}
	
	@Bean(name="cacheManager",destroyMethod =  "destroy")
	public EhCacheManager ehCacheManager() {
		EhCacheManager cacheManager = new EhCacheManager();
		cacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
		return cacheManager;
	}

	/*@Bean
	public SimpleCookie simpleCookie() {
	    SimpleCookie cookie = new SimpleCookie();
	    cookie.setName("linkdcs.sessionId");
	    return cookie;
    }*/
	
	public ModularRealmAuthenticator  modularRealmAuthenticator(){
		ModularRealmAuthenticator  ma =new ModularRealmAuthenticator();
//		ma.setAuthenticationStrategy();
		return ma;
	}


    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();

        //验证逻辑
//        securityManager.setAuthenticator(authenticator);
        //权限控制
        securityManager.setRealm(myShiroRealm());
//        securityManager.setRealms(realms);
        //session管理
        securityManager.setSessionManager(defaultWebSessionManager());
       
        //cacheManager 
        securityManager.setCacheManager(ehCacheManager());
        
//        securityManager.setRememberMeManager(rememberMeManager);
        //缓存管理
        return securityManager;
    }

}
